#include "net.h"

#include <algorithm>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdio.h>
#include <vector>
#include <iostream>

#include <xmmintrin.h>  //sse
#include <face.h>

using namespace std;


void pretty_print(const ncnn::Mat& m)
{
    printf("%d ", m.c);
    printf("\n");
    printf("%d ", m.h);
    printf("\n");


    for (int q=0; q<m.c; q++)
    {
        const float* ptr = m.channel(q);
        for (int y=0; y<m.h; y++)
        {
            for (int x=0; x<m.w; x++)
            {
                printf("%f ", ptr[x]);
            }
            ptr += m.w;
            printf("\n");
        }
        printf("------------------------\n");
    }

}

float simd_dot(const float* x, const float* y, const long& len) {
    float inner_prod = 0.0f;
    __m128 X, Y; // 128-bit values
    __m128 acc = _mm_setzero_ps(); // set to (0, 0, 0, 0)
    float temp[4];

    long i;
    for (i = 0; i + 4 < len; i += 4) {
        X = _mm_loadu_ps(x + i); // load chunk of 4 floats
        Y = _mm_loadu_ps(y + i);
        acc = _mm_add_ps(acc, _mm_mul_ps(X, Y));
    }
    _mm_storeu_ps(&temp[0], acc); // store acc into an array
    inner_prod = temp[0] + temp[1] + temp[2] + temp[3];

    // add the remaining values
    for (; i < len; ++i) {
        inner_prod += x[i] * y[i];
    }
    return inner_prod;
}

//计算欧式距离
float calcSimilarity(const float* fc1,const float* fc2,long dim) {

    return simd_dot(fc1, fc2, dim)/ (sqrt(simd_dot(fc1, fc1, dim)) * sqrt(simd_dot(fc2, fc2, dim)));
}
//获取特征
ncnn::Mat getFeatByMobileFaceNetNCNN(ncnn::Extractor ex,cv::Mat img){
    ncnn::Mat in = ncnn::Mat::from_pixels_resize(img.data, ncnn::Mat::PIXEL_BGR, img.cols, img.rows, 112, 112);

    ex.input("data", in);
    ncnn::Mat out;
    ex.extract("fc1", out);
//    pretty_print(out);
    return out;
}

